<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
        "http://www.w3.org/TR/html4/strict.dtd">

<script type="text/javascript"> var djConfig = { isDebug: true } </script>
<script type="text/javascript" src="../../release/dojo/dojo.js"></script>

<style type="text/css">
	pre { border: 1px solid black; padding: 1em; background: #eee; }
</style>

<script type="text/javascript">

function props (e, name, descend) {
	if (arguments.length == 2) { descend = true; }
	var ns = ["Methods", "Properties", "Unreachables"];
	var as = [[], [], []]; // array of (empty) arrays of arrays!
	var p, j, i; // loop variables, several used multiple times

	var protoLevels = 0;

	for (p = e; p; p = p.__proto__) {
		for (i = 0; i < ns.length; ++i) { as[i][protoLevels] = []; }
		++protoLevels;
	}

	var propLength = function (o) { var i = 0; for (p in o) { i++; }; return i; }

	for (var a in e) {
		// Shortcoming: doesn't check that VALUES are the same in object and prototype.

		var protoLevel = -1;
		try {
			for (p = e; p && (a in p); p = p.__proto__) { ++protoLevel; }
		} catch (er) { protoLevel = 0; } // "in" operator throws when param to props() is a string

		var type = 1;
		try {
			if (dojo.lang.isFunction(e[a])) { type = 0; }
		} catch (er) { type = 2; }

		if (a.indexOf("$joinpoint") != -1 || a.indexOf("_") == 0
			|| a.lastIndexOf("_") == a.length - 1) { continue; }

		if (type == 1 && /^[A-Z]/.test(a) && propLength(e[a]) == 0) { continue; }

		as[type][protoLevel].push(a);
	}

	function times (s, n) { return n ? s + times(s, n-1) : ""; }

	if (name.split(".").length == 2) {
		document.body.appendChild(document.createTextNode("\n------" + name.split(".")[1] + "\n"));
	}

	for (j = 0; j < 1 && j < protoLevels; ++j) {
		var h2 = document.createElement("h2");
		h2.appendChild(document.createTextNode(name));
		h2.setAttribute("id", name);
		document.body.appendChild(h2);
		for (i = 0;i < ns.length; ++i) {
			if (as[i][j].length)  {
				var h3 = document.createElement("h3");
				h3.appendChild(document.createTextNode(ns[i]));
				document.body.appendChild(h3);
				
				var pre = document.createElement("pre");
				for (var k = 0; k < as[i][j].length; k++) {
					if (i == 1) {
						var obj = e[as[i][j][k]];
						with (dojo.lang) {
							if (isArray(obj)) { var type = "Array"; }
							else if (isNumber(obj)) { var type = "Number"; }
							else if (isString(obj)) { var type = "String"; }
							else if (isBoolean(obj)) { var type = "Boolean"; }
							else if (isUndefined(obj)) { var type = "undefined"; }
							else { var type = "Object"; }
						}
						pre.appendChild(document.createTextNode(type + " "));
						if (type == "Object" && (propLength(obj) > 0 || /^[A-Z]/.test(as[i][j][k]))) {
							var a = document.createElement("a");
							a.href = "#" + name + "." + as[i][j][k];
							a.appendChild(document.createTextNode(as[i][j][k]));
							pre.appendChild(a);
						} else {
							pre.appendChild(document.createTextNode(as[i][j][k]));
						}
						pre.appendChild(document.createTextNode("\n"));
					} else if (i == 0) {
						pre.appendChild(document.createTextNode(as[i][j][k] + " "));
						var args = e[as[i][j][k]].toString().match(/\([^\)]*\)/)[0];
						pre.appendChild(document.createTextNode(args + "\n"));
					} else {
						pre.appendChild(document.createTextNode(as[i][j][k] + "\n"));					
					}
				}
				document.body.appendChild(pre);
			}
		}
		if (document.body.lastChild == h2) { document.body.removeChild(h2); }
	}
	
	if (descend) {
	
		if (as[0][0]) {
			for (i = 0; i < as[0][0].length; i++) {
				if (/^[A-Z]/.test(as[0][0][i])) { // Object constructor
					try {
						var obj = new e[as[0][0][i]];
						props(obj, name + "." + as[0][0][i] + " Object", false);
					} catch (e) {}
				}	
			}
		}
		if (as[1][0]) {
			for (i = 0; i < as[1][0].length; i++) {
				if (typeof e[as[1][0][i]] == "object" && !(e[as[1][0][i]] instanceof Array)) {
					props(e[as[1][0][i]], name + "." + as[1][0][i], true);
				}
			}
		}
	}
}

dojo.event.connect(window, "onload", function (e) {
	props(dojo, "dojo", true);
});

</script>

<h2>Globals</h2>

<pre>dj_undef
dj_eval_object_path
dj_error_to_string
dj_debug
dj_throw
dj_rethrow
dj_eval
dj_unimplemented
dj_deprecated
dj_inherits
dj_load
dj_last_script_src
dj_addNodeEvtHdlr</pre>

<pre>djConfig
dj_global
dojo
DJ_XMLHTTP_PROGIDS
dojo_ie_clobber</pre>
